package com.nulldev.util.concurrency.threadIt.v4.emapi.testing;

import com.nulldev.util.JVM.JVM;
import com.nulldev.util.concurrency.threadIt.v4.asyncTasks.AsyncTaskCallback;
import com.nulldev.util.concurrency.threadIt.v4.emapi.ExecutorManager;
import com.nulldev.util.concurrency.threadIt.v4.emapi.uft.Executable;

public class ExecutableFailing {

	public static void main(String[] args) {
		Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {

			@Override
			public void uncaughtException(Thread thread, Throwable throwable) {
				if (throwable == null)
					return;
				JVM.errorln(throwable);
			}
		});
		JVM.println("Failing via NULL_PTR_WAIT_TILL");
		try {
			final Executable<?> o = ExecutorManager.globalAsyncSubmit(() -> {
				return ((String) null).length();
			});
			o.waitTillCompletion();
		} catch (Exception e) {
			JVM.errorln(e);
		}
		try {
			JVM.println("Failing via NULL_PTR_ASYNC_CB");
			@SuppressWarnings("unused")
			final Executable<Integer> o = ExecutorManager.globalAsyncSubmit(() -> {
				return ((String) null).length();
			}).addCallback(new AsyncTaskCallback<Integer>() {

				@Override
				public void onCompletion(Integer result) {
					JVM.println("onCompletion: result");
				}

				@Override
				public void onError(Throwable e) {
					JVM.errorln(e);
				}

			});
		} catch (Exception e) {
			JVM.errorln(e);
		}
		try {
			JVM.println("Failing via MULTI_LAYER_FAIL");
			@SuppressWarnings("unused")
			final Executable<Integer> o = ExecutorManager.globalAsyncSubmit(() -> {
				return ((String) null).length();
			}).addCallback(new AsyncTaskCallback<Integer>() {

				@Override
				public void onCompletion(Integer result) {
					JVM.println("onCompletion: result");
					ExecutorManager.globalAsyncSubmit(() -> {
						return ((String) null).length();
					}).waitTillCompletion();
				}

				@Override
				public void onError(Throwable e) {
					JVM.errorln(e);
				}

			});
		} catch (Exception e) {
			JVM.errorln(e);
		}
		try {
			JVM.println("Failing via MULTI_LAYER_FAIL_WITH_AWAIT");
			@SuppressWarnings("unused")
			final Integer o = ExecutorManager.globalAsyncSubmit(() -> {
				return ((String) null).length();
			}).addCallback(new AsyncTaskCallback<Integer>() {

				@Override
				public void onCompletion(Integer result) {
					JVM.println("onCompletion: result");
					((String) null).length();
				}

				@Override
				public void onError(Throwable e) {
					JVM.errorln(e);
				}

			}).waitTillCompletion();
		} catch (Exception e) {
			JVM.errorln(e);
		}
		try {
			JVM.println("Failing via MULTI_LAYER_FAIL_WITH_AWAIT2");
			@SuppressWarnings("unused")
			final Integer o = ExecutorManager.globalAsyncSubmit(() -> {
				return ((String) null).length();
			}).addCallback(new AsyncTaskCallback<Integer>() {

				@Override
				public void onCompletion(Integer result) {
					JVM.println("onCompletion: result");
				}

				@Override
				public void onError(Throwable e) {
					JVM.errorln(e);
					ExecutorManager.globalAsyncSubmit(() -> {
						return ((String) null).length();
					}).waitTillCompletion();
				}

			}).waitTillCompletion();
		} catch (Exception e) {
			JVM.errorln(e);
		}
	}

}
